package com.hit.client.driver.netty.strategy;

import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.StrUtil;
import com.hit.client.driver.dto.GfRobotStatusOfCar;
import com.hit.client.driver.netty.protocol.message.GfMessage;
import com.hit.client.driver.util.GfCacheUtil;
import com.hit.client.driver.util.GfToolkit;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Optional;

/**
 * 换行车 消息解析
 */
@Slf4j
public class Gf7CStrategy implements GfMessageHandlerStrategy {

    @Override
    public void handle(ChannelHandlerContext ctx, GfMessage message) {
        // 获取消息中的数据
        byte[] data = message.getData();
        int mainCmd = data[0] & 0xFF;//转换为无符号
        int subCmd = data[1] & 0xFF;//转换为无符号
        boolean reslut = true;
        // 分配 ByteBuf 并将数据写入
        ByteBuf buffer = ctx.alloc().buffer(data.length);
        buffer.writeBytes(data);
        try {
            mainCmd = buffer.readByte() & 0xFF;
            subCmd = buffer.readByte() & 0xFF;
            //机器人编码
            byte[] sn = new byte[4];
            buffer.readBytes(sn);
            String robotSerial = HexUtil.encodeHexStr(sn);
            switch (subCmd) {
                case 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 -> {
                    reslut = buffer.readByte() == (byte) 0x00;
                }
                case 0x11 -> {
                    //获取机器设备工作状态(含返回实时转速) 0x7C+0x11
                    short reachStatus = buffer.readShortLE();//上报心跳间隔时间 单位：毫秒 2byte
                    short qdlSpeed = buffer.readShortLE();//驱动轮速度（R/min） 2byte
                    int qdlMotorDis = buffer.readIntLE();//驱动轮电机里程计 4byte
                    float qdlMotorCurrent = BigDecimal.valueOf(buffer.readShortLE()).divide(BigDecimal.valueOf(100).setScale(2, RoundingMode.HALF_UP)).floatValue();//驱动轮电机电流（0.01A） 2byte
                    float qdlMotorVoltage = BigDecimal.valueOf(buffer.readShortLE()).divide(BigDecimal.valueOf(10).setScale(2, RoundingMode.HALF_UP)).floatValue();//驱动轮电机电压（0.1V） 2byte
                    short qdlMotorTemperature = buffer.readShortLE();//驱动轮电机温度（℃） 2byte
                    int bmqDis = buffer.readIntLE();//编码器里程计 4byte
                    float zkbVoltage = BigDecimal.valueOf(buffer.readShortLE()).divide(BigDecimal.valueOf(1000).setScale(2, RoundingMode.HALF_UP)).floatValue();//主控板电压（0.001V） 2byte
                    float dcVoltage = BigDecimal.valueOf(buffer.readShortLE()).divide(BigDecimal.valueOf(10).setScale(2, RoundingMode.HALF_UP)).floatValue();//电池电压（0.1V）2byte
                    byte workStatus = buffer.readByte();//机器人工作状态 0x00：机器空闲  0x01：机器工作 0x10：电机堵转 0x11：通讯异常 0x12：电量过低 0x20：进入程序状态 0x21：程序升级中  0x22：程序升级完成
                    byte robotWorkFlowStatus = buffer.readByte();//光伏机器人工作流程状态 0x10：光伏机器人就位 0x11：光伏机器人离开
                    byte carWorkFlowStatus = buffer.readByte();//换行车工作流程状态 0x00：机器人、驱动轮插销解锁 0x01：机器人插销解锁，驱动轮插销锁死 0x10：机器人插销锁死，驱动轮插销解锁 0x11：机器人插销锁死，驱动轮插销锁死
                    byte carLocationStatus = buffer.readByte();//换行车位置状态 0x00：处于起点 0x01：处于终点
                    byte carPositionStatus = buffer.readByte();//换行车点位状态 0x01：处于一号点位 0x02：处于二号点位 0x03：处于三号点位 0x04：处于四号点位 ......
                    byte driverEnable = buffer.readByte();//电机使能状态 0x00：电机未使能 0x01：电机使能
                    byte carTaskStatus = buffer.readByte();//换行车任务状态 0x00：换行车空闲 0x01：换行车自动任务 0x02：交由上位机控制
                    short power = buffer.readShortLE();//电池电量
                    GfRobotStatusOfCar gfRobotStatusOfCar = GfRobotStatusOfCar.builder()
                            .robotSerial(robotSerial).reachStatus(reachStatus).qdlSpeed(qdlSpeed)
                            .qdlMotorDis(qdlMotorDis).qdlMotorCurrent(qdlMotorCurrent).qdlMotorVoltage(qdlMotorVoltage)
                            .qdlMotorTemperature(qdlMotorTemperature).bmqDis(bmqDis).zkbVoltage(zkbVoltage).dcVoltage(dcVoltage)
                            .workStatus(workStatus).robotWorkFlowStatus(robotWorkFlowStatus).carWorkFlowStatus(carWorkFlowStatus)
                            .carLocationStatus(carLocationStatus).carPositionStatus(carPositionStatus).driverEnable(driverEnable)
                            .carTaskStatus(carTaskStatus).power(power)
                            .build();
                    GfCacheUtil.put(robotSerial, GfCacheUtil.KEY_ROBOT_STATUS_OF_CAR, gfRobotStatusOfCar);
                }
                case 0x12 -> {
                    GfRobotStatusOfCar lastStatus = Optional.ofNullable((GfRobotStatusOfCar) GfCacheUtil.get(robotSerial, GfCacheUtil.KEY_ROBOT_STATUS_OF_CAR)).orElse(GfRobotStatusOfCar.builder().build());
                    if (StrUtil.isBlank(lastStatus.getRobotSerial())) {
                        log.info("[gf-car] get robot serial number:{}", robotSerial);
                    }

                    //保存通道
                    boolean isRelay = message.getLength() == 8;
                    log.info("[gf-car] get isRelay status:{}", isRelay);
                    if (isRelay) {
                        //继电器通道
                        GfToolkit.relayCtxOfCarMap.put(robotSerial, ctx);
                        log.info("[gf-car]save relay ctx,{}", ctx);
                    } else {
                        GfToolkit.ctxOfCarMap.put(robotSerial, ctx);
                        log.info("[gf-car]save chip ctx,{}", ctx);
                    }
                    log.info("[gf-car] get ChannelHandlerContext:{} success", ctx);
                }
            }
            GfToolkit.release(robotSerial, message, reslut);
        } catch (Exception e) {
            log.error("[gf-car]deal  {}{}-message error,{}", String.format("%02x", mainCmd), String.format("%02x", subCmd), e.getMessage());
        } finally {
            // 确保 ByteBuf 在使用完后释放，防止内存泄漏
            buffer.release();
        }
    }


}
